import React, {
  Dispatch,
  createContext,
  useCallback,
  useContext,
  useReducer,
} from 'react';

export type StateType = {
  [key: string]: any;
};

export type ContextType = {
  state: StateType;
  dispatch: Dispatch<{
    type: string;
    payload?: Partial<StateType>;
  }>;
};

export type ReducerContextProps = {
  /** 初始化状态 */
  initState: StateType;
};

const useReducerContext = ({
  initState = {},
}: ReducerContextProps): [(p: any) => JSX.Element, () => ContextType] => {
  const Context = createContext<ContextType>({
    state: initState,
    dispatch: () => {},
  });

  const Provider = ({ children }: any) => {
    const reducer = useCallback(
      (
        preState: StateType,
        action: {
          type: string;
          payload?: Partial<StateType>;
        },
      ) => {
        const { type, payload } = action;
        switch (type) {
          default:
            return preState;
          case 'upgrade':
            return {
              ...preState,
              ...payload,
            };
        }
      },
      [],
    );
    const [state, dispatch] = useReducer(reducer, initState);
    return (
      <Context.Provider value={{ state, dispatch }}>
        {children}
      </Context.Provider>
    );
  };

  const Contexts = () => useContext(Context);

  return [Provider, Contexts];
};

export { useReducerContext };
